#include <cstring>
#include <ctime>
#include <stdexcept>
#include <string>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>

#define LIKELY(x) __builtin_expect(!!(x), 1)
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#define BASEAME(file) (strrchr(file, '/') ? (strrchr(file, '/') + 1) : file)

namespace xncc {
namespace common {
    auto exists(const std::string& file) -> bool;
    auto createPath(const std::string& spath) -> bool;
    auto unixtimestampToStr(int64_t tms) -> std::string;
    auto timevalToStr(const struct timeval* tmv) -> std::string;
    auto timeNowStr() -> std::string;
    auto appendPath(const std::string& path, const std::string& file) -> std::string;

    struct system_exception : public std::logic_error
    {
        explicit system_exception(const std::string& what = "")
            : std::logic_error("system error:" + what + " " + strerror(errno))
        {
        }
    };
}  // namespace common

#define TRACE_DEBUG(fmt, args...)                                                                                      \
    do {                                                                                                               \
        fprintf(stderr, "%s %s:%d(%s): " fmt "\n", common::timeNowStr().data(), BASEAME(__FILE__), __LINE__,           \
                __FUNCTION__, ##args);                                                                                 \
                                                                                                                       \
    } while (0)

#define TRACE_SYSTEM(fmt, args...)                                                                                     \
    do {                                                                                                               \
        fprintf(stderr, "%s %s:%d(%s)[%s]: " fmt "\n", common::timeNowStr().data(), BASEAME(__FILE__), __LINE__,       \
                __FUNCTION__, strerror(errno), ##args);                                                                \
                                                                                                                       \
    } while (0)
}  // namespace xncc